﻿using Project2004.Jigsaw.Helpers;
using Project2004.Jigsaw.Utils;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Project2004.Jigsaw.Models
{
    /// <summary>
    /// 拼图的场景。
    /// </summary>
    public class Scene
    {
        public List<MovableBlock> Blocks { get; set; } = new List<MovableBlock>();
        public List<LogicalGroup> Groups { get; set; } = new List<LogicalGroup>();

        public double Size { get; set; }
        public int ColumnCount { get; set; }
        public int RowCount { get; set; }

        public int TotalCount => ColumnCount * RowCount;

        public Scene()
        {

        }

        public Scene(double imageWidth, double imageHeight, int columnCount, int rowCount)
        {
            Size = Math.Min(imageWidth / columnCount, imageHeight / rowCount);
            ColumnCount = columnCount;
            RowCount = rowCount;

            var matrix = new Block[columnCount, rowCount];

            for (int i = 0; i < columnCount; i++)
            {
                for (int j = 0; j < rowCount; j++)
                {
                    matrix[i, j] = new Block()
                    {
                        Id = new BlockId(i, j),
                        X = i,
                        Y = j,
                        JigsawConfig = new JigsawConfig()
                        { Bottom = HoleType.Flat, Left = HoleType.Flat, Right = HoleType.Flat, Top = HoleType.Flat }
                    };
                }
            }

            for (int i = 0; i < columnCount; i++)
            {
                for (int j = 0; j < rowCount - 1; j++)
                {
                    var block1 = matrix[i, j];
                    var block2 = matrix[i, j + 1];
                    var randomValue = RandomHelper.GetRandom(HoleType.In, HoleType.Out);
                    var reverseValue = InsertDirectionHelper.Reverse(randomValue);

                    block1.JigsawConfig.Bottom = randomValue;
                    block2.JigsawConfig.Top = reverseValue;
                }
            }

            for (int j = 0; j < rowCount; j++)
            {
                for (int i = 0; i < columnCount - 1; i++)
                {
                    var block1 = matrix[i, j];
                    var block2 = matrix[i + 1, j];
                    var randomValue = RandomHelper.GetRandom(HoleType.In, HoleType.Out);
                    var reverseValue = InsertDirectionHelper.Reverse(randomValue);

                    block1.JigsawConfig.Right = randomValue;
                    block2.JigsawConfig.Left = reverseValue;
                }
            }

            for (int i = 0; i < columnCount; i++)
            {
                for (int j = 0; j < rowCount; j++)
                {
                    var block = matrix[i, j];
                    Groups.Add(new LogicalGroup() { Blocks = new List<BlockId>() { block.Id } });
                    Blocks.Add(new(block));
                }
            }

        }


        public List<LogicalGroupModel> GetGroups()
        {
            var dict = Blocks.ToDictionary(i => i.Id);
            var list = new List<LogicalGroupModel>();

            foreach (var group in Groups)
            {
                if (group.Blocks.Count == 0) continue;
                var groupModel = new LogicalGroupModel();
                groupModel.Key = group;
                foreach (var blockId in group.Blocks)
                {
                    var block = dict[blockId];
                    groupModel.Blocks.Add(block);
                }
                list.Add(groupModel);
            }
            return list;
        }

    }
}
